package com.xbongbong.paas.call;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.pojo.DetaPhonePojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.ListOptionEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.elasticsearch.common.inject.Singleton;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @author 吴峰
 * @date 2021/12/20 17:03
 */
@Component
public class AliyunCall {

    private static final Logger LOGGER = LoggerFactory.getLogger(AliyunCall.class);

    @Resource
    private CallCenterService callCenterService;

    /**
     * 是否启用
     */
    private boolean enable;

    private boolean activeCallEnable;

    private boolean aliyunCallEnable;

    private UserVO userVO;

    private Map<Long, List<String>> mainUser;

    private Map<Long, List<String>> coUser;

    private Integer businessType;

    private Integer subBusinessType;

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public boolean isActiveCallEnable() {
        return activeCallEnable;
    }

    public void setActiveCallEnable(boolean activeCallEnable) {
        this.activeCallEnable = activeCallEnable;
    }

    public boolean isAliyunCallEnable() {
        return aliyunCallEnable;
    }

    public void setAliyunCallEnable(boolean aliyunCallEnable) {
        this.aliyunCallEnable = aliyunCallEnable;
    }

    public UserVO getUserVO() {
        return userVO;
    }

    public void setUserVO(UserVO userVO) {
        this.userVO = userVO;
    }

    public Map<Long, List<String>> getMainUser() {
        return mainUser;
    }

    public void setMainUser(Map<Long, List<String>> mainUser) {
        this.mainUser = mainUser;
    }

    public Map<Long, List<String>> getCoUser() {
        return coUser;
    }

    public void setCoUser(Map<Long, List<String>> coUser) {
        this.coUser = coUser;
    }

    public Integer getBusinessType() {
        return businessType;
    }

    public void setBusinessType(Integer businessType) {
        this.businessType = businessType;
    }

    public Integer getSubBusinessType() {
        return subBusinessType;
    }

    public void setSubBusinessType(Integer subBusinessType) {
        this.subBusinessType = subBusinessType;
    }

    public AliyunCall() {
        enable = false;
        activeCallEnable = false;
        aliyunCallEnable = false;
    }

    public AliyunCall(boolean enable, boolean activeCallEnable, boolean aliyunCallEnable, UserVO userVO) {
        this.enable = enable;
        this.activeCallEnable = activeCallEnable;
        this.aliyunCallEnable = aliyunCallEnable;
        this.userVO = userVO;
    }

    public AliyunCall(boolean enable, boolean activeCallEnable, boolean aliyunCallEnable, UserVO userVO, Map<Long, List<String>> mainUser, Map<Long, List<String>> coUser, Integer businessType, Integer subBusinessType) {
        this.enable = enable;
        this.activeCallEnable = activeCallEnable;
        this.aliyunCallEnable = aliyunCallEnable;
        this.userVO = userVO;
        this.mainUser = mainUser;
        this.coUser = coUser;
        this.businessType = businessType;
        this.subBusinessType = subBusinessType;
    }

    private AliyunCall getAliyunCall(String corpid, UserVO userVO, Integer businessType, Integer subBusinessType) throws XbbException {
        String userId = userVO.getUserId();
        // 判断是否有呼叫权限
        boolean isActiveCall = false;
        List<Integer> list = Arrays.asList(XbbRefTypeEnum.CUSTOMER_RECYCLE.getCode(), XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(), XbbRefTypeEnum.CLUE_PUBLIC.getCode(), XbbRefTypeEnum.CLUE_RECYCLE.getCode());
        if (!list.contains(subBusinessType)) {
            // com.xbongbong.saas.help.SaasListHelp.setOptionBase(java.util.List<java.lang.Long>, com.xbongbong.paas.pojo.dto.FormDataListDTO, com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO, java.lang.Long) 这个方法，只有子业务不等于这些才会判断
            isActiveCall = callCenterService.isOpenCallAndAgent(corpid, userId);
        }
        // 判断是否有阿里云呼叫中心权限
        boolean isActiveAliyunCall = callCenterService.isActiveAliyunCall(corpid,userId).IsActiveAliyunAndHasRole();

        return new AliyunCall(isActiveCall|| isActiveAliyunCall, isActiveCall, isActiveAliyunCall, userVO);
    }


    /**
     * 设置拨打电话的字段，将其放入字段列表中
     * @param corpid 公司id
     * @param userVO 用户权限相关
     * @param list 字段列表
     * @param mainUser 负责人
     * @param coUser 协同人
     * @param businessType 业务类型
     * @param subBusinessType 子业务类型
     * @return
     * @throws XbbException
     */
    public AliyunCall setAliCallField( String corpid, UserVO userVO, List<FieldAttrEntity> list, Map<Long, List<String>> mainUser, Map<Long, List<String>> coUser, Integer businessType, Integer subBusinessType) throws XbbException {
        AliyunCall aliyunCall = getAliyunCall( corpid, userVO, businessType, subBusinessType);
        if (aliyunCall.isEnable()) {
            FieldAttrEntity fieldCall = new FieldAttrEntity();
            fieldCall.setAttr(ListOptionEnum.CALL.getAttr());
            fieldCall.setAttrName(ListOptionEnum.CALL.getAttrName());
            fieldCall.setFieldType(FieldTypeEnum.CALL.getType());
            fieldCall.setDisableListSort(1);
            // 这里不一定需要将拨打电话放在第一位，因为后面还会重排序，可改
            list.add(0, fieldCall);
        }
        aliyunCall.setSubBusinessType(subBusinessType);
        aliyunCall.setBusinessType(businessType);
        aliyunCall.setMainUser(mainUser);
        aliyunCall.setCoUser(coUser);
        return aliyunCall;
    }

    /**
     * 设置拨号
     * @param aliyunCall 阿里云呼
     * @param corpid 公司id
     * @param paasFormDataEntityExt 字段数据
     * @param explainMap 字段容器
     * @param phoneAttr 联系电话字段 一般都是subForm_1
     */
    public void setCallData( AliyunCall aliyunCall, String corpid, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap, String phoneAttr) {
        try {
            if (!aliyunCall.isEnable()) {
                return;
            }
            Long dataId = paasFormDataEntityExt.getId();
            JSONObject data = paasFormDataEntityExt.getData();
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            handlerExplainDTO.setLoginUser(aliyunCall.getUserVO());
            handlerExplainDTO.setUserId(aliyunCall.getUserVO().getUserId());
            List<String> ownerIdList = new ArrayList<>();
            if (aliyunCall.getMainUser().containsKey(dataId)) {
                ownerIdList = aliyunCall.getMainUser().get(dataId);
            }
            handlerExplainDTO.setOwnerId(ownerIdList);
            List<String> coUserIdList = new ArrayList<>();
            if (aliyunCall.getCoUser().containsKey(dataId)) {
                coUserIdList = aliyunCall.getCoUser().get(dataId);
            }
            handlerExplainDTO.setCoUserId(coUserIdList);
            handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getCreatorId());
            boolean isActiveCall = aliyunCall.isActiveCallEnable();
            boolean isActiveAliyunCall = aliyunCall.isAliyunCallEnable();
            JSONObject json = new JSONObject();
            int value = 0;
            JSONArray customerPhoneArray = FastJsonHelper.getJsonArrFromFormData(data, phoneAttr);
            int aliyunCallCenterValue = 0;
            if (customerPhoneArray != null && !customerPhoneArray.isEmpty()) {
                JSONObject item = customerPhoneArray.getJSONObject(0);
                String tel = item.getString(StringConstant.PHONE_TEL_ATTR);
                if (Objects.nonNull(tel) && !StringUtil.isEmpty(tel)) {
                    value = 1;
                    aliyunCallCenterValue = 1;
                }
            }
            if(!isActiveCall){
                value = 0;
            }
            Integer subBusinessType = aliyunCall.getSubBusinessType();
            Integer businessType = aliyunCall.getBusinessType();
            //  为客户回收站 客户联系人 线索回收站 线索联系人 就不展示
            if(Objects.equals(subBusinessType, XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode())
                    || Objects.equals(subBusinessType, XbbRefTypeEnum.CUSTOMER_RECYCLE.getCode())
                    || Objects.equals(subBusinessType, XbbRefTypeEnum.CLUE_PUBLIC.getCode())
                    || Objects.equals(subBusinessType, XbbRefTypeEnum.CLUE_RECYCLE.getCode())){
                value = 0;
            }
            List<DetaPhonePojo> detaPhonePojos = callCenterService.cusCallPhone(data, businessType, corpid, explainMap, handlerExplainDTO);
            json.put("value", value);
            json.put("dial",detaPhonePojos);
            if(!isActiveAliyunCall){
                aliyunCallCenterValue = 0;
            }
            json.put("aliyunCallCenterValue", aliyunCallCenterValue);
            json.put("aliyunCallCenterDial", detaPhonePojos);
            data.put(ListOptionEnum.CALL.getAttr(), json);

            // 客户电话设置不可见，拨号列应隐藏。
            boolean flag = false;
            if ( explainMap != null) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(phoneAttr);
                if (Objects.isNull(fieldAttrEntity)) {
                    return;
                }
                SubFormPoJo subForm = fieldAttrEntity.getSubForm();
                List<? extends FieldAttrEntity> items = subForm.getItems();
                if(CollectionsUtil.isNotEmpty(items)){
                    for (FieldAttrEntity item : items) {
                        if(StringConstant.PHONE_TEL_ATTR.equals(item.getAttr())){
                            if (BasicConstant.ZERO.equals(item.getVisible())) {
                                flag = true;
                                break;
                            }
                        }
                    }
                }
                if (BasicConstant.ZERO.equals(fieldAttrEntity.getVisible())||flag) {
                    json.put("value", 0);
                    json.put("dial",detaPhonePojos);
                    json.put("aliyunCallCenterValue", 0);
                    json.put("aliyunCallCenterDial", detaPhonePojos);
                    data.put(ListOptionEnum.CALL.getAttr(), json);
                }

            }
        } catch (Exception e) {
            LOGGER.error("com.xbongbong.paas.call.AliyunCall.setCallData error", e);
        }

    }



    /**
     * 设置呼叫电话
     *
     * @param corpid   公司id
     * @param explainMap 解释
     * @param customer          客户
     * @throws XbbException
     * @author long.rao
     * @date 2019-03-22 13:52
     */
    public static boolean checkShowCall(String corpid, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntityExt customer) throws XbbException {
        JSONObject data = customer.getData();
        JSONArray customerPhoneArray = FastJsonHelper.getJsonArrFromFormData(data, CustomerManagementEnum.PHONE.getAttr());
        if (customerPhoneArray == null || customerPhoneArray.isEmpty()) {
            //没有电话，直接返回
            return false;
        }
        //电话可见判断
        FieldAttrEntity explainEntity = explainMap.get(CustomerManagementEnum.PHONE.getAttr());
        if (explainEntity != null && Objects.equals(explainEntity.getIsOpen(), 0)) {
            return false;
        }
        for (int i = 0; i < customerPhoneArray.size(); i++) {
            JSONObject item = customerPhoneArray.getJSONObject(i);
            String tel = item.getString(StringConstant.PHONE_TEL_ATTR);
            if (tel != null) {
                if (Objects.equals(tel, "")) {
                    return false;
                }
            }else{
                return false;
            }
        }
        return true;
    }

    /**
     * 设置呼叫电话
     *
     * @param explainMap 解释
     * @param customer          客户
     * @param others            其他
     * @throws XbbException
     * @author long.rao
     * @date 2019-03-22 13:52
     */
    public static void setCallPhone(String corpid, EsHelper esHelper, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntityExt customer, JSONObject others) throws XbbException {
        JSONObject data = customer.getData();
        Long customerId = customer.getDataId();
        JSONArray customerPhoneArray = FastJsonHelper.getJsonArrFromFormData(data, CustomerManagementEnum.PHONE.getAttr());
        if (customerPhoneArray == null || customerPhoneArray.isEmpty()) {
            //没有电话，直接返回
            return;
        }
        // 列表封装关联联系人号码
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("data." + ContactEnum.CUSTOMER_NAME.getAttr(), customerId));
        boolQueryBuilder.filter(termQuery("del", 0));
        // 限制返回值
        List<String> fieldList = Arrays.asList(FieldTypeEnum.DATAID.getAlias(), ContactEnum.getAttrConnectData(ContactEnum.NAME), ContactEnum.getAttrConnectData(ContactEnum.PHONE));
        List<PaasFormDataEntityExt> contactList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTACT, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);

        // TODO 判断电话字段属否可见
        //redundantFieldExplainModel.setAttrVisibility(userEntity, customer, explainEntityList);
        //电话可见判断
        Integer attrVisible = 0;
        FieldAttrEntity explainEntity = explainMap.get(CustomerManagementEnum.PHONE.getAttr());
        if (explainEntity != null && Objects.equals(explainEntity.getIsOpen(), 1)) {
            attrVisible = 1;
        }
        JSONArray customerArr = new JSONArray();
        for (int i = 0; i < customerPhoneArray.size(); i++) {
            JSONObject customerObj = new JSONObject();
            JSONObject item = customerPhoneArray.getJSONObject(i);
            String tel = item.getString(StringConstant.PHONE_TEL_ATTR);
            customerObj.put("id", customer.getDataId());
            customerObj.put("refType", XbbRefTypeEnum.CUSTOMER.getCode());
            customerObj.put("name", data.getOrDefault(CustomerManagementEnum.NAME.getAttr(), ""));
            customerObj.put("telNum", tel);
            if (tel != null) {
                if (!Objects.equals(tel, "")) {
                    customerObj.put("phoneNum", tel);
                    if (attrVisible == 0) {
                        String telNum = "";
                        if (tel.length() > 5) {
                            telNum = tel.substring(0, 3) + "****" + tel.substring(tel.length() - 2);
                        } else {
                            telNum = StringConstant.INVISIBLE_VALUE;
                        }
                        customerObj.put("telNum", telNum);
                    }
                } else if (Objects.equals(tel, "")) {
                    customerObj.put("phoneNum", "");
                }
            }else{
                continue;
            }
            customerArr.add(customerObj);
        }
        if (!customerArr.isEmpty()) {
            others.put("customerDial", customerArr);
        }
        if (contactList.isEmpty()) {
            //没有电话，直接返回
            return;
        }
        JSONArray contactPhoneArray = new JSONArray();
        for (PaasFormDataEntityExt contact : contactList) {
            JSONObject contactData = contact.getData();
            JSONArray tempPhoneArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(contactData, ContactEnum.PHONE.getAttr(), new JSONArray());
            if (tempPhoneArray == null || tempPhoneArray.size() == 0) {
                continue;
            }
            JSONObject contactObj = new JSONObject();
            for (Object item : tempPhoneArray) {
                JSONObject contactPhoneObj = (JSONObject) item;
                if (contactPhoneObj.containsKey(StringConstant.PHONE_TEL_ATTR)) {
                    if (contactPhoneObj.get(StringConstant.PHONE_TEL_ATTR) != null) {
                        String phoneTel = contactPhoneObj.getString(StringConstant.PHONE_TEL_ATTR);
                        contactObj.put("telNum", phoneTel);
                        if (!Objects.equals(phoneTel, "")) {
                            contactObj.put("phoneNum", phoneTel);
                            if (attrVisible == 0) {
                                String telNum = "";
                                if (phoneTel.length() > 5) {
                                    telNum = phoneTel.substring(0, 3) + "****" + phoneTel.substring(phoneTel.length() - 2);
                                } else {
                                    telNum = StringConstant.INVISIBLE_VALUE;
                                }
                                contactObj.put("telNum", telNum);
                            }
                        } else if (Objects.equals(phoneTel, "")) {
                            contactObj.put("phoneNum", "");
                        }
                    }
                    String contactName = FastJsonHelper.getStringOrDefaultFromFormData(contactData, ContactEnum.NAME.getAttr(), "");
                    contactObj.put("id", contact.getDataId());
                    contactObj.put("refType", XbbRefTypeEnum.CONTACT.getCode());
                    contactObj.put("name", contactName);
                    contactPhoneArray.add(contactObj);
                }
            }
        }
        if (!contactPhoneArray.isEmpty()) {
            others.put("contactDial", contactPhoneArray);
        }
        //前端用于判断呼叫中心相关
        others.put("isCallCenter", true);
    }
}
